#pragma once
#include <iostream>
#include <sys/select.h>
#include <unistd.h>
#include <cstdlib>
#include <sys/epoll.h>
#include <memory>
#include <sys/time.h>
#include "Socket.hpp"
#include"Common.hpp"
#include"Connection.hpp"
#include<map>

#define MAX_FD_NUM 256


using namespace std;
class Epoll
{
public:
    Epoll() : _is_running(false)
    {
        
    }
    void Init()
    {
        
        int n = _epollfd = epoll_create(MAX_FD_NUM); // 创建epoll句柄
        if (n < 0)
        {
            cout << "epoll_create error" << endl;
            exit(1);
        }

        cout << "Init Over" << endl;
    }
    void Loop(const unordered_map<int ,shared_ptr<Connection>>& connections)
    {
        _is_running = true;
        while (_is_running)
        {
            int n = epoll_wait(_epollfd, _epes, MAX_FD_NUM, 5000); // 单位是毫秒
            switch (n)
            {
            case -1:
                cout << "select error" << endl;
                break;
            case 0:
                cout << "timeout" << endl;
                break;
            default:
                Handrequest(connections,n);
                break;
            }
        }
    }

    void Setepoll(uint32_t event,int fd)
    {
        struct epoll_event ev;
        ev.events = event;
        ev.data.fd = fd;
        epoll_ctl(_epollfd, EPOLL_CTL_ADD, fd, &ev);
    }

    void Removeepoll(int fd)
    {
        epoll_ctl(_epollfd, EPOLL_CTL_DEL, fd, nullptr);
    }

    void Handrequest(const unordered_map<int ,shared_ptr<Connection>>& connections, int maxfd)
    {
        for (int i = 0; i < maxfd; i++)
        {
            if(_epes[i].data.fd==DEFAULT_FD)
                continue;
            int fd=_epes[i].data.fd;
            if(_epes[i].events & EPOLLIN)
            {
                connections.find(fd)->second->Handle_read();
            }
            if(_epes[i].events & EPOLLOUT)
            {
                connections.find(fd)->second->Handle_write();
            }
            if(_epes[i].events & EPOLLERR)
            {
                connections.find(fd)->second->Handle_error();
            }       
        }
    }




private:
    bool _is_running;
    int _epollfd;
    struct epoll_event _epes[MAX_FD_NUM];
};
